import { isReferee } from "@/func";
import { GameMode, ItemStack, Player } from "@minecraft/server";
import { Dimensions } from "@sapi-game/constants";
import { AutoStopComponent } from "@sapi-game/gameComponent/common/autoStop";
import { Timer } from "@sapi-game/gameComponent/common/timer/timer";
import { RegionTeamCleaner } from "@sapi-game/gameComponent/region/regionTeamCleaner";
import { PlayerGroupSet } from "@sapi-game/gamePlayer/groupSet";
import { SphereRegion } from "@sapi-game/gameRegion/gameRegion";
import { AutoStopState } from "@sapi-game/gameState/common/autoStop";
import { Game } from "@sapi-game/main";
import { DimensionIds, EffectIds } from "@sapi-game/utils/vanila-data";
import { PillarOfFortuneLobbyStarter } from "../components/lobby";
import { PillarOfFortuneModule } from "../module";
import { PillarOfFortuneLoadingState } from "./loadingState";

export class PillarOfFortuneLobbyState extends PillarOfFortuneModule.State {
    readonly BASE_TIME = 30;

    override onEnter(): void {
        this.addComponent(Timer, { initialTime: this.BASE_TIME });
        this.addComponent(AutoStopComponent, {
            groupSet: new PlayerGroupSet([this.context.players]),
            immediateDie: true,
            onStopGame: () => this.engine.stopGame(),
            onLeave: () => {},
        });
        //自动清理过远玩家
        this.addComponent(PillarOfFortuneLobbyStarter).addComponent(
            RegionTeamCleaner,
            {
                teams: [this.context.players],
                region: new SphereRegion(
                    DimensionIds.Overworld,
                    { x: 442, y: 10, z: 1043 },
                    10
                ),
            }
        );
        //瞬间治疗
        this.subscribe(Game.events.interval, () => {
            this.context.players.forEach((p) =>
                p.addEffect(EffectIds.InstantHealth, 10)
            );
        });
        this.setupAdminShortcuts();
        this.context.players.forEach((p) => this.tryJoin(p.player));
    }

    /** 管理员使用钻石快速开始 */
    private setupAdminShortcuts() {
        this.subscribe(
            Game.events.itemUse,
            (t) => {
                if (!isReferee(t.source)) return;

                const timer = this.getComponent(Timer);
                timer.start();
                if (timer.time > 10) {
                    timer.set(10);
                    this.context.players.sendMessage("管理员已加速游戏开始");
                }
            },
            {
                itemId: "minecraft:diamond",
                players: this.context.players,
            }
        );
    }

    /** 玩家加入房间 */
    tryJoin(player: Player) {
        if (!player.isValid) return;

        const { players, map } = this.context;
        if (players.validSize >= map.startPoints.length) {
            player.sendMessage("房间已满员，无法加入");
            return;
        }

        const gamePlayer = this.playerManager.get(player);
        if (!gamePlayer.isValid) return;

        player.teleport(map.watingPoint);
        player.setGameMode(GameMode.Adventure);
        player.runCommand("clear @s");
        player.setSpawnPoint({
            ...map.watingPoint,
            dimension: Dimensions.Overworld,
        });
        if (isReferee(player)) {
            gamePlayer.giveItem(new ItemStack("diamond"));
        }

        players.add(gamePlayer);
        players.sendMessage(
            `§e${gamePlayer.name} §r加入了房间 (${players.validSize}/${map.startPoints.length})`
        );
        players.playSound("open.wooden_door");
    }

    getStats() {
        return {
            cur: this.context.players.validSize,
            max: this.context.map.startPoints.length,
        };
    }

    /** 启动正式游戏 */
    start() {
        if (this.context.players.validSize < 1) return;

        this.engine.resetState(AutoStopState, {
            groupSet: new PlayerGroupSet([this.context.players]),
            immediateDie: true,
            onLeave: (p) =>
                this.context.players.sendMessage(`${p.name} 退出了幸运之柱`),
        });
        this.pushState(PillarOfFortuneLoadingState);
    }
}
